#ifndef OOBB2_H
#define OOBB2_H

#include "Vec2.h"
#include "Vec3.h"
#include "RadiansAndDegreesConverter.h"
#include "RBContactData.h"
#include "ObjMeshManager.h"

#include <D3DX11.h>
#include <D3DX10math.h>

struct BoxPoints2
{
	BoxPoints2()
	{
		corners[0] = Vec2f(0, 0);
		corners[1] = corners[0];
		corners[2] = corners[0];
		corners[3] = corners[0];
	}
	Vec2f corners[4];
};

struct OOBB2
{
	BoxPoints2 bp;
	OOBB2(){}
	OOBB2(Vec2f mp, Vec2f ax[], float ex[])
	{
		axis[0] = ax[0];
		axis[1] = ax[1];
		axis[0].Normalise();
		axis[1].Normalise();

		centre = mp;
		extents[0] = ex[0];
		extents[1] = ex[1];
	}
	OOBB2(Vec2f mp, Vec2f ax1, Vec2f ax2, float ex1, float ex2)
	{
		axis[0] = ax1;
		axis[1] = ax2;
		axis[0].Normalise();
		axis[1].Normalise();

		centre = mp;
		extents[0] = ex1;
		extents[1] = ex2;
	}

	Vec2f centre;
	Vec2f axis[2]; // direction of the vector
	float extents[2]; // how long the axis is
};

void CalculateOOBBCorners(const OOBB2& oob, BoxPoints2& bp);
void CalculateOOBBCorners(const OOBB2& oob, Vec2f f[]);
bool CheckCollisionOOBB(const OOBB2& oobb1, const OOBB2& oobb2);


struct BoxPoints3
{
	BoxPoints3()
	{
		corners[0] = D3DXVECTOR3(0, 0, 0);
		corners[1] = corners[0];
		corners[2] = corners[0];
		corners[3] = corners[0];
		corners[4] = corners[0];
		corners[5] = corners[0];
		corners[6] = corners[0];
		corners[7] = corners[0];
	}
	D3DXVECTOR3 corners[8];
};

struct RoomCorners
{
	RoomCorners()
	{
		size = 0;
		maxPoints = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	}
	D3DXVECTOR3 maxPoints;
	float size;
};

struct OOBB3
{
	BoxPoints3 bp;
	OOBB3()
	{
		axis[0] = D3DXVECTOR3(1, 0, 0);
		axis[1] = D3DXVECTOR3(0, 1, 0);
		axis[2] = D3DXVECTOR3(0, 0, 1);

		centre = D3DXVECTOR3(0, 0, 0);

		extents[0] = 1;
		extents[1] = 1;
		extents[2] = 1;

		//quat[0] = Quaternion(0, axis[0].x, axis[0].y, axis[0].z);
		//quat[1] = Quaternion(0, axis[1].x, axis[1].y, axis[1].z);
		//quat[2] = Quaternion(0, axis[2].x, axis[2].y, axis[2].z);
	}

	OOBB3(D3DXVECTOR3 mp, D3DXVECTOR3 ax[], float ex[])
	{
		axis[0] = ax[0];
		axis[1] = ax[1];
		axis[2] = ax[2];

		D3DXVec3Normalize(&axis[0], &axis[0]);
		D3DXVec3Normalize(&axis[1], &axis[1]);
		D3DXVec3Normalize(&axis[2], &axis[2]);

		centre = mp;

		extents[0] = ex[0];
		extents[1] = ex[1];
		extents[2] = ex[2];
	}
	OOBB3(D3DXVECTOR3 mp, D3DXVECTOR3 ax1, D3DXVECTOR3 ax2, D3DXVECTOR3 ax3, float ex1, float ex2, float ex3)
	{
		axis[0] = ax1;
		axis[1] = ax2;
		axis[2] = ax3;

		D3DXVec3Normalize(&axis[0], &axis[0]);
		D3DXVec3Normalize(&axis[1], &axis[1]);
		D3DXVec3Normalize(&axis[2], &axis[2]);

		centre = mp;

		extents[0] = ex1;
		extents[1] = ex2;
		extents[2] = ex3;
	}

	// don't need axisparam
	void Rotate(float angle, const D3DXVECTOR3& axisParam)
	{
		D3DXMATRIX tempMat;
		D3DXMATRIX mat1;
		D3DXMatrixIdentity(&mat1);
		//mat1 = XMMatrixRotationRollPitchYaw(axisParam.x * angle, axisParam.y * angle, axisParam.z * angle);
		D3DXMatrixRotationX(&tempMat, axisParam.x * angle);
		mat1 *= tempMat;
		D3DXMatrixRotationY(&tempMat, axisParam.y * angle);
		mat1 *= tempMat;
		D3DXMatrixRotationZ(&tempMat, axisParam.z * angle);
		mat1 *= tempMat;

		axis[0] = D3DXVECTOR3(mat1._11, mat1._12, mat1._13);
		axis[1] = D3DXVECTOR3(mat1._21, mat1._22, mat1._23);
		axis[2] = D3DXVECTOR3(mat1._31, mat1._32, mat1._33);
	}

	void Draw();

	D3DXVECTOR3 centre;
	D3DXVECTOR3 axis[3]; // direction of the vector
	float extents[3]; // how long the axis is
};

void CalculateOOBBCorners(const OOBB3& oob, BoxPoints3& bp);
void CalculateOOBBCorners(const OOBB3& oob, Vec3f f[]);
bool CheckCollisionOOBB(const OOBB3& oobb1, const OOBB3& oobb2);

#endif // OOBB2_H